﻿import axios, {AxiosRequestConfig} from 'axios';
import {bus} from '@/components/common/common';

declare module 'axios' {
  interface AxiosRequestConfig {
    showMessage?: boolean;
  }
}

export const baseUrl = location.origin;

export async function request<T = unknown>(config: AxiosRequestConfig): Promise<T> {
  try {
    const result = (await axios.request({
      baseURL: baseUrl,
      ...config
    })).data;
    if (result.constructor === Object) {
      return result.data;
    } else {
      return result;
    }
  } catch (error: unknown) {
    console.dir(error);
    const errorObj = error as ({ response: { data: { message: string } } } & Error);
    const message = errorObj?.response.data.message ?? errorObj?.message ?? '未知错误';
    if (config.showMessage !== false) {
      bus.$message({type: 'error', message});
    }
    throw new Error(message);
  }
}

export function getPuzzleItems() {
  return request<Array<PuzzleItem>>({
    url: '/api/puzzleItems',
    method: 'get',
    showMessage: true
  });
}

export function init() {
  return request<void>({
    url: '/api/init',
    method: 'get',
    showMessage: true
  });
}

export function bind(puzzleFileName: string, fileId: number) {
  return request<void>({
    url: '/api/bind',
    params: {puzzleFileName, fileId},
    method: 'get',
    showMessage: true
  });
}

export function openPreviewFile() {
  return request<{path: string, url: string}>({
    url: '/api/previewFile',
    method: 'get',
    showMessage: true
  });
}

export function openMapFile() {
  return request<{path: string, fileName: string, fileSize: number}>({
    url: '/api/mapFile',
    method: 'get',
    showMessage: true
  });
}

export function rename(oldName: string, newName: string) {
  return request<void>({
    url: '/api/rename',
    method: 'get',
    params: {oldName, newName},
    showMessage: true
  });
}

export function showInWorkshop(fileId: number) {
  return request<void>({
    url: '/api/showInWorkshop',
    method: 'get',
    params: {fileId},
    showMessage: true
  });
}

export function queryWorkshopItem(fileId: number) {
  return request<PuzzleItem>({
    url: '/api/queryWorkshopItem',
    method: 'get',
    params: {fileId},
    showMessage: true
  });
}


export function execCommand(command: string) {
  return request<void>({
    url: '/api/execCommand',
    method: 'get',
    params: {command},
    showMessage: true
  });
}

export function submit(item: PuzzleItem) {
  return request<void>({
    url: '/api/submit',
    method: 'post',
    data: item,
    showMessage: true
  });
}

export function cloneMap(item: PuzzleItem) {
  return request<void>({
    url: '/api/cloneMap',
    method: 'post',
    data: item,
    showMessage: true
  });
}

export function query(queryInfo: QueryInfo) {
  return request<Array<PuzzleItem>>({
    url: '/api/query',
    method: 'get',
    params: queryInfo,
    showMessage: true
  });
}

export function operate(fileId: number, type: string) {
  return request<number>({
    url: '/api/operate',
    method: 'get',
    params: {fileId, type},
    showMessage: true
  });
}

export function getAbsoluteUrl(url: string, baseUrl = location.origin) {
  return new URL(url, baseUrl).toString();
}

export interface PuzzleItem {
  fileId: number;

  type: number;

  coop: boolean;

  chamberSize: string;

  visibility: number;

  tags: Array<string>;

  puzzleFileName: string;

  mapFilePath: string;

  previewFilePath: string;

  workshop: PublishInfo;

  local: PublishInfo;
}

export interface QueryInfo {
  queryWay: 'author' | 'item';

  authorUrl: string;

  authorType: string;

  itemUrl: string;
}

export interface PublishInfo {
  title: string;

  description: string;

  createTime: string;

  updateTime: string;

  mapFileName: string;

  mapFileSize: number;

  preview: string;
}
